package com.goldman.aplt.base.task;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zhuwei
 */
public class ThreadPoolBase {
	
	static ThreadPoolExecutor executor = null;
	/* 缺省大小为 cpu个数的 2倍 */
	static final int DEFAULT_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;
	/* 缺省最大线程数为 cpu个数的4倍  */
	static final int DEFAULT_MAX_SIZE = Runtime.getRuntime().availableProcessors() * 4;
	
	public static ThreadPoolExecutor getExecutor() {
        if (executor == null) {
            executor = createThreadPoolExecutor(DEFAULT_POOL_SIZE, DEFAULT_MAX_SIZE);
        }
        return executor;
    }
	
	// 生成固定大小的线程池，执行任务
	private static ThreadPoolExecutor createThreadPoolExecutor(int nThreads, int maxThreads) {
	    return new ThreadPoolExecutor(nThreads, maxThreads,
	            1000L, TimeUnit.MILLISECONDS,
	            new LinkedBlockingQueue<Runnable>(), new DefaultThreadFactory());
	}

   static class DefaultThreadFactory implements ThreadFactory {
        static final AtomicInteger poolNumber = new AtomicInteger(1);
        final ThreadGroup group;
        final AtomicInteger threadNumber = new AtomicInteger(1);
        final String namePrefix;

        DefaultThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null)? s.getThreadGroup() :
                                 Thread.currentThread().getThreadGroup();
            namePrefix = "BusiTask-" +
                          poolNumber.getAndIncrement() +
                         "-worker-";
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                                  namePrefix + threadNumber.getAndIncrement(),
                                  0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }

}
